#include "write_buf.h"

namespace qio {

WriteBuf::~WriteBuf() QIO_NOEXCEPT {
  if (write_result_cb_) {
    write_result_cb_(this, write_idx_ == data_len_);
  }
  if (!own_ || data_ == nullptr) {
    return;
  }
  delete[] data_;
}

WriteBuf::WriteBuf(const char *data, std::size_t data_len, bool own,
                   DoneCallback &&cb) QIO_NOEXCEPT
    : own_(own),
      data_len_(data_len),
      data_(own_ ? data : new char[data_len_]),
      write_result_cb_(std::forward<DoneCallback>(cb)),
      write_idx_(0) {
  if (!own) {
    memcpy(const_cast<char *>(data_), data, data_len);
    own_ = true;
  }
}

WriteBuf::WriteBuf(WriteBuf &&o) QIO_NOEXCEPT
    : own_(o.own_),
      data_len_(o.data_len_),
      data_(o.data_),
      write_result_cb_(std::move(o.write_result_cb_)),
      write_idx_(o.write_idx_) {
  o.data_ = nullptr;
  o.write_result_cb_ = nullptr;
  o.write_idx_ = 0;
}

WriteBuf &WriteBuf::operator=(WriteBuf &&o) QIO_NOEXCEPT {
  if (this == &o) {
    return *this;
  }
  if (write_result_cb_) {
    write_result_cb_(this, write_idx_ == data_len_);
  }
  if (own_ && data_ != nullptr) {
    delete[] data_;
  }
  own_ = o.own_;
  data_len_ = o.data_len_;
  data_ = o.data_;
  write_result_cb_ = o.write_result_cb_;
  write_idx_ = o.write_idx_;
  o.data_ = nullptr;
  o.write_result_cb_ = nullptr;
  o.write_idx_ = 0;
  return *this;
}

}  // namespace qio
